var http = require('http');
const jwt = require('jsonwebtoken');
import configFile from './config';
import { base64 } from './core/enco';
import app from './app';
import mongodbHandle from './handle/mongodbHandle'
import routeHandle from './handle/routeHandle'
import rankHandle from './handle/rankHandle';
import * as url from 'url'
import * as cluster from 'cluster'
import * as os from 'os'
import redisHandle from './handle/redisHandle';
// import playerHandle from 'js/handle/playerHandle';
import moment = require('moment');
import worldBossHandle from './handle/worldBossHandle';
var cp = require('child_process');
var cpuCount = os.cpus().length;
var ObjectId = require('mongodb').ObjectId;
var log4js = require('log4js')
import * as child_process  from 'child_process';
if (process.argv.length >= 2 && configFile[process.argv[2]]) {
    app.env = process.argv[2]
    app.config = configFile[process.argv[2]]
} else {
    app.env = 'dev'
    app.config = configFile['dev']
}

log4js.configure(app.config.log4js)

app.logger = log4js.getLogger('default')


let getResData = async (data) => {
    data.time = new Date().getTime()
    data.version = app.version
    data.dtime = moment().startOf('day').valueOf()
    data = JSON.stringify(data)
    if (app.env == 'pro' || app.env == 'demo') {
        data = base64.encode(data)
    }
    return data
}

var httpapp = async (req, res) => {
    res.setHeader('Access-Control-Allow-Credentials', 'true');
    res.setHeader("Access-Control-Allow-Origin", "*");
    res.setHeader('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');
    res.setHeader("Access-Control-Allow-Headers", "X-Requested-With,cache-control,content-type,hash-referer,authorization,testclient");

    let reqs = req.url.split('/')
    let api = reqs[reqs.length - 2]
    let reqUrl = reqs[reqs.length - 1]
    //升级维护中
    if (app.serverState !== 0 && reqUrl.indexOf("setServerState") == -1) {
        let testclient = req.headers.testclient
        if (req.method === 'GET' || req.method === 'get' || req.method === 'post' || req.method === 'POST') {
            if (!testclient) {
                res.end(
                    await getResData({
                        err: 110,
                        data: app.stateText
                    })
                )
                return
            }
        }
    }
    if (req.method === 'GET' || req.method === 'get') {
        if (req.url.indexOf("notifycharge") !== -1) {
            try {
                let query = url.parse(req.url).query
                let data = {}
                query.split('&').forEach(item => {
                    let d = item.split('=')
                    data[d[0]] = d[1]
                })
                let resData = await routeHandle("notifycharge", data, null)
                res.end(await getResData(resData))
            } catch (e) {
                res.end()
            }
        }
    } else if (req.method === 'POST') {
        var data = "";
        req.on("data", (chunk) => {
            data += chunk;
        })
        req.on("end", async () => {
            let token = req.headers.authorization
            let dataJson
            if (api == 'api') {
                try {
                    if (app.env == 'pro' || app.env == 'demo') {
                        data = base64.decode(data)
                    }
                    dataJson = JSON.parse(data);
                } catch (e) {
                    res.end(
                        await getResData({
                            err: 105,
                            data: e.message
                        })
                    )
                }
                if (token) {
                    jwt.verify(token, "secretkey", async (err, decode) => {
                        if (!err) {
                            let resData = await routeHandle(reqUrl, dataJson, decode)
                            res.end(await getResData(resData))
                        } else {
                            let resData = await routeHandle(reqUrl, dataJson, null)
                            res.end(await getResData(resData))
                        }
                    })
                } else {
                    let resData = await routeHandle(reqUrl, dataJson, null)
                    res.end(await getResData(resData))
                }
            } else {
                res.end()
            }
        })
    } else {
        res.end()
    }
};

let forkInit = async () => {
    console.log('worker:' + cluster.worker.id)
    await redisHandle.init('worker:' + cluster.worker.id)
    await mongodbHandle.init('worker:' + cluster.worker.id)
    if (app.env == 'demo' || app.env == 'dev') {
        // await mongodbHandle.initTest('mongodb://root:123456789qwe@183.56.208.170:27017', 'wuxiapro')
    }
    let server = http.createServer(httpapp);
    server.listen(app.config.port, (err) => {
        console.log(`worker:${cluster.worker.id} 服务器环境: ${app.env} 端口:${app.config.port}`)
    });

    // await rankHandle.init()

    process.on('message', function (msg) {
        if (msg.message == "setVersion") {
            console.log("setVersion", msg.version)
            app.version = msg.version
        } else if (msg.message == "setServerState") {
            app.serverState = msg.serverState
            app.stateText = msg.stateText || "服务器在维护中"
        }
    });

    for (var i = 0; i < cpuCount && i < 1; i++) {
        let fork = child_process.fork('./dist/fork.js', [i + "", ...process.argv.slice(2)]);
        fork.on('message', function (msg) {
            if (msg.messageID) {
                let messageID = msg.messageID
                if (app.forkmessageCb[messageID]) {
                    app.forkmessageCb[messageID](msg)
                    delete app.forkmessageCb[messageID]
                }
            } else if (msg.message == "playerAmount") {
                app.playerSessionForks[msg.forkID].amount = msg.playerAmount
                console.log('delete', msg.pIDs)
                msg.pIDs.forEach(pID=>{
                    delete app.playerSessionForksByID[pID]
                })
            }
        })
        app.playerSessionForks.push({ fork, amount: 0 })
    }
}


let masterInit = async () => {
    console.log('master主进程')
    await redisHandle.init('master主进程')
    await mongodbHandle.init('master主进程')
    // if (app.env == 'demo' || app.env == 'dev') {
    //     await mongodbHandle.initTest('mongodb://root:123456789qwe@183.56.208.170:27017', 'swordpro')
    // }
    let server = http.createServer(httpapp);
    server.listen(app.config.masterPort);
    console.log(`master 服务器环境: ${app.env} 端口:${app.config.masterPort}`)

    // var n = cp.fork('./dist/arenaAutoMain.js');
    // app.arenaFork = n
    // n.send({ "message": "version", "version": app.version });
    // n.send({ "message": "start", "env": app.env });
    // var csn = cp.fork('./dist/csArenaMain.js');
    // app.csFork = csn
    // csn.send({ "message": "version", "version": app.version });
    // csn.send({ "message": "start", "env": app.env });
    // console.log('启动子进程:' + cpuCount)
    // let j = 0
    // let timer = setInterval(() => {
    //     csTest()
    //     j += 1
    //     if (j > 10) {
    //         clearInterval(timer)
    //     }
    // }, 2000)

    // csTest2()
    for (var i = 0; i < 1; i++) {
        cluster.fork();
    }

    for (const id in cluster.workers) {
        let worker = cluster.workers[id]
        worker.on('message', (message) => {
            if (app.arenaFork && app.arenaFork.send) {
                if (message.message == 'arenaAutoAddPlayer') {
                    app.arenaFork.send({ "message": "arenaAutoAddPlayer", "pID": message.pid });
                } else if (message.message == 'csArenaAddPlayer') {
                    app.csFork.send({ "message": "csArenaAddPlayer", "pID": message.pid, serverID: message.serverID });
                }
            }
        });
    }
   
    await rankHandle.init()
    await worldBossHandle.schedule()
    await rankHandle.schedule()
}

let start = async () => {
    if (cluster.isMaster) {
        await masterInit()
    } else {
        forkInit()
    }
}

start()

var fs = require('fs');
var join = require('path').join;

function writeFile(path, data, filename) {
    fs.writeFile(path + "/" + filename.split(".")[0] + "." + filename.split(".")[1], data, function (error) {
        if (error) {
            console.log(path + ' ' + filename + " error");
            // throw error;
        } else {
            console.log(filename + "文件已保存");
        }
    });
}

// forkinit()
